const webpack = require('webpack');
const path = require('path');
const globalConfig = require('./src/config.js');


const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');


// bundle split, 尝试把这些比较独立的库单独放在一个js文件中
// 注意只有真正"公用"的库才能放这里, 否则会有各种奇怪的问题
// 而且必须在bundle.js之前加载
const vendorLibs = ['react', 'react-router',
    'redux', 'react-redux', 'redux-logger', 'redux-thunk', 'redux-promise',
    'superagent',
];

module.exports = {
    devtool: 'cheap-module-source-map',

    entry: [
        'babel-polyfill',
        './src/index.js',
    ],

    output: {
        path: path.join(__dirname, globalConfig.outputPath + '/dist'), // 用来存放打包后文件的输出目录
        publicPath: '/dist/', // 指定资源文件引用的目录
        filename: 'bundle.min.js'
    },


    resolve: {
        modules: [
            "node_modules",
            path.resolve(__dirname, "app")
        ],
        extensions: ['*', '.js', '.jsx']
    },

    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                loader: 'babel-loader',
                options: {
                    plugins: [
                        ['import', [{libraryName: 'antd', style: true}]],
                    ],
                    cacheDirectory: true,
                },
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', "less-loader"]
            },
            {
                test: /\.(svg|eot|ttf|woff)$/,
                use: ['file-loader']
            },
            {
                test: /\.(png|jpg|gif)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 10000
                        }
                    }
                ]
            }
        ]
    },

    plugins: [
        // 代码压缩
        new webpack.optimize.UglifyJsPlugin({
            sourceMap: true,
            minimize: true,
            compress: {warnings: false},
            output: {comments: false},
        }),

        new HtmlWebpackPlugin({
            template: 'index.html',// 模板文件
            filename: '../index.html',// 入口文件
            title: globalConfig.name,
            favIcon: globalConfig.favicon,
            hash: true,  // 引入js/css的时候加个hash, 防止cdn的缓存问题
            minify: {removeComments: true, collapseWhitespace: true},
        }),

        // 抽离公共部分, 要了解CommonsChunkPlugin的原理, 首先要搞清楚chunk的概念
        // CommonsChunkPlugin做的其实就是把公共模块抽出来, 可以单独生成一个新的文件, 也可以附加到已有的chunk上
        // 同时还会加上webpack的runtime相关代码
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            filename: 'vendor.min.js',
            // 这个函数决定哪些模块会被放到vender.min.js中
            minChunks: (module) => {
                // 得到资源路径
                var resource = module.resource;
                if (!resource)
                    return false;
                // 坑爹的webpack, for-of里不用能const, 会有bug
                for (var libName of vendorLibs) {
                    if (resource.indexOf(path.resolve(__dirname, 'node_modules', libName)) >= 0)
                        return true;
                }
                return false;
            },
        }),

        new webpack.optimize.AggressiveMergingPlugin(),
        // 允许错误不打断程序
        new webpack.NoEmitOnErrorsPlugin(),

        // css单独抽出来
        new ExtractTextPlugin('bundle.min.css', {allChunks: false}),
        // 压缩成gzip格式
        new CompressionPlugin({
            asset: "[path].gz[query]",
            algorithm: "gzip",
            test: /\.js$|\.css$|\.html$/,
            threshold: 10240,
            minRatio: 0,
        }),

        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
            __DEV__: JSON.stringify(JSON.parse(process.env.NODE_ENV === 'production' ? 'false' : 'true')),
        }),
    ],
};
